#!/usr/bin/python

"""Utilities for working with local running circuit processes."""

from __future__ import division, print_function

import os
import os.path
import subprocess

class Error(Exception):
  """Module-level error."""

class NoCircuitRunning(Error):
  """Failed to find a local circuit process."""

class NoMountFound(Error):
  """Failed to find a local circuit mount point."""

class NoXidsFound(Error):
  """Failed to find any XIDs in, e.g., the cluster/IP/ dir."""

class NoCircuitArgs(Error):
  """Failed to obtain running circuit arguments."""

def find_mount():
  """Find the mount point for a locally-running circuit."""

  # TODO(chris): make this less Linux-centric.
  # We might get away with using "mount" to find it, but ps and cmdline are
  # more reliable.

  proc = subprocess.Popen("pgrep circuit", shell=True, stdout=subprocess.PIPE)
  cpid, _ = proc.communicate()
  cpid = cpid.strip()

  if not cpid:
    raise NoCircuitRunning()

  procdir = os.path.join("/proc", cpid, "cmdline")
  copts = None
  if os.path.exists(procdir):
    copts = open(procdir, "r").read().split('\x00')
  else:
    # Try running ps to get the arguments (unreliable when things have spaces)
    ps = subprocess.Popen("ps -p {} -o args=".format(cpid),
                          shell=True, stdout=subprocess.PIPE)
    args, _ = ps.communicate()
    copts = args.strip().split()

  if not copts:
    raise NoCircuitArgs()

  for i, opt in enumerate(copts):
    if opt.startswith('-m='):
      return opt[3:]
    elif opt == '-m':
      return copts[i+1]
  raise NoMountFound()

def local_lang(circuitbase=None):
  """Find a path to 'lang' for the local circuit instance.

  Args:
    circuitbase: the mount point of the local circuit, uses find_mount if None

  Returns:
    a path to a lang on the local machine
  """
  if circuitbase is None:
    circuitbase = find_mount()

  local = os.path.join(circuitbase, "cluster/127.0.0.1")
  xids = os.listdir(local)
  if not xids:
    raise NoXidsFound("No XIDs found in {!r}".format(local))
  return os.path.join(local, xids[0], "lang")
